package com.caowei.weicimpress.weicimpress;

import android.annotation.TargetApi;
import android.content.Context;
import android.net.ConnectivityManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import dalvik.system.DexFile;

/**
 * Created by caoweiPc on 2014/7/18.
 */
public class Utils {
    public static final boolean DEBUG=true;
    public static int CORESIZE=Runtime.getRuntime().availableProcessors();
    public static final String NOTIFYTASKCHANGE_ACTION="com.caowei.weicimpress.weicimpress.NOTIFYTASKCHANGE";
    public static final String NOTIFYFILESYSTEMCHANGEINCURRENTDIR_ACTION="com.caowei.weicimpress.weicimpress.NOTIFYSYSTEMCHANGEINCURRENTDIR";
    public static final String NOTIFYCOMPRESSSYSTEMCHANGE_ACTION="com.caowei.weicimpress.weicimpress.NOTIFYSYSTEMCHANGE";
    public static final int SELECTED="selected".hashCode();
    public static final int SYSFRAG_TAB_INDEX=0;
    public static final int COMPRESSFRAG_TAB_INDEX=1;
    public static final int SEARCH_TAB_INDEX=2;
    public static final int TASKFRAG_TAB_INDEX=3;

    public static final int EXITINTERVAL=2000;
    private static final String TAG=Utils.class.getSimpleName();
    public static final String DEFAULTDATEPATTERN="yyyy-MM-dd:hh:mm:ss";
    public static final String DEFAULTDATEPATTERNWITHA="yyyy-MM-dd a hh:mm:ss";
    public static final String DEFAULTDATEPATTERNNOTWITHMMSS="yyyy-MM-dd";

    public static final String DEFAULTDECIMALFORMATPATTERN="0.00";
    public static final float SIZEUNIT=1024f;
    public static final String UNITS[]={"B","KB","MB","GB","TB","PB","EB","ZB","YB"};
    public static enum UNIT{
        B,KB,MB,GB,TB,PB,EB,ZB,YB
    }


    public static final int MAXSLEEPTIME=Integer.MAX_VALUE;
    private static ThreadLocal<SimpleDateFormat> threadLocalDf=new ThreadLocal<SimpleDateFormat>(){
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat(DEFAULTDATEPATTERN);
        }
    };
    private static ThreadLocal<DecimalFormat> threadLocalDecimalFormat=new ThreadLocal<DecimalFormat>()
    {
        @Override
        protected DecimalFormat initialValue() {
            return new DecimalFormat(DEFAULTDECIMALFORMATPATTERN);
        }
    };
  //    pixes
    public static final int ACTIONBARBTNW=100;

    public static List<Class> getSubClsFromParent(Context context, Class parentCls) {
        List<Class> result=new ArrayList<Class>();

        String pkName=context.getPackageName();
        String path= context.getPackageResourcePath();
        try {
            //todo  暂时 以后缓存到数据库中
            Log.d(TAG, pkName);
            DexFile df=new DexFile(path);
            Enumeration<String> entries= df.entries();
            while (entries.hasMoreElements()){
                String clN=entries.nextElement();
                if(clN.startsWith(pkName)&&!clN.contains("$")&&!clN.equals(parentCls.getName())){
                    Log.d(TAG,clN);
                    Class cl=Class.forName(clN);

                    if(!cl.isInterface()&& Modifier.isPublic(cl.getModifiers())
                            &&!Modifier.isAbstract(cl.getModifiers())&&parentCls.isAssignableFrom(cl)){
                        result.add(cl);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return result;
    }

    private static SimpleDateFormat getDateFormater(){
        return threadLocalDf.get();
    }

    public static String formateDate(Calendar calendar){
        return getDateFormater().format(calendar.getTime());
    }

    public static String formateDate(Calendar calendar,String pattern){
        SimpleDateFormat format=getDateFormater();
        format.applyPattern(pattern);
        String dateStr= format.format(calendar.getTime());
        format.applyPattern(DEFAULTDATEPATTERN);
        return dateStr;
    }

    public static String formateDate(long time_millis,String pattern){
        SimpleDateFormat format=getDateFormater();
        format.applyPattern(pattern);
        Date date=new Date(time_millis);
        String dateStr= format.format(date);
        format.applyPattern(DEFAULTDATEPATTERN);
        return dateStr;
    }

    public static String formateDate(long time_millis){
        SimpleDateFormat format=getDateFormater();
        Date date=new Date(time_millis);
        String dateStr= format.format(date);
        return dateStr;
    }

    public static String formateDecimat(float f){
        DecimalFormat dft=threadLocalDecimalFormat.get();
        String result= dft.format(f);
        return result;
    }

    public static String formateDecimat(float f,String pattern){
        DecimalFormat dft=threadLocalDecimalFormat.get();
        dft.applyPattern(pattern);
        String result= dft.format(f);
        dft.applyPattern(DEFAULTDECIMALFORMATPATTERN);
        return result;
    }

    public static String normalSizeStr(BigDecimal size){
        StringBuilder sb=new StringBuilder();
        int i=0;
        int compare= size.compareTo(BigDecimal.valueOf(1000));
        while (compare>0){
            size=size.divide(BigDecimal.valueOf(SIZEUNIT));
            i++;
            compare= size.compareTo(BigDecimal.valueOf(1000));
        }
        sb.append(formateDecimat(size.floatValue())).append(UNITS[i]);
        return sb.toString();
    }

    public static long getFileSize(File f) {
        long size = 0;
        File flist[] = f.listFiles();

        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size = size + getFileSize(flist[i]);
            } else {
                size = size + flist[i].length();
            }
        }
        return size;
    }

    public static long getFileSize2(File f) {
        long size = 0;
        File flist[] = f.listFiles();
        File file;
        for (int i = 0; i < flist.length; i++) {
            file=flist[i];
            if (file.isDirectory()) {
                size = size + getFileSize(file);
            } else {
                size = size + file.length();
            }
        }
        return size;
    }

    public static void exit(){
        exit(0);
    }

    public static void exit(int code){
        ActivityManager.getInstance().finishAll();
        ExecuteFileHandler.getInstance().clear();
        MyApplication application= MyApplication.getMyApplication();
        if(application!=null){
            application.clear();
        }
        System.exit(code);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static BigDecimal getExternalAllSpace(){
        BigDecimal result=BigDecimal.ZERO;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File exterDir=Environment.getExternalStorageDirectory();
            StatFs statFs=new StatFs(exterDir.getPath());
           if(Build.VERSION_CODES.JELLY_BEAN_MR2 >Build.VERSION.SDK_INT){
                long blockCount= statFs.getBlockCount();
                long blockSize= statFs.getBlockSize();
               result=BigDecimal.valueOf(blockCount).multiply(BigDecimal.valueOf(blockSize));
            }else{
                long blockCount= statFs.getBlockCountLong();
                long blockSize= statFs.getBlockSizeLong();
               result=BigDecimal.valueOf(blockCount).multiply(BigDecimal.valueOf(blockSize));
            }
        }
        return result;
    }


    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static BigDecimal getInternalAllSpace(){
        BigDecimal result=BigDecimal.ZERO;
        File internalDir=Environment.getRootDirectory();
        StatFs statFs=new StatFs(internalDir.getPath());
        if(Build.VERSION_CODES.JELLY_BEAN_MR2 >Build.VERSION.SDK_INT){
            long blockCount= statFs.getBlockCount();
            long blockSize= statFs.getBlockSize();
            result=BigDecimal.valueOf(blockCount).multiply(BigDecimal.valueOf(blockSize));
        }else{
            long blockCount= statFs.getBlockCountLong();
            long blockSize= statFs.getBlockSizeLong();
            result=BigDecimal.valueOf(blockCount).multiply(BigDecimal.valueOf(blockSize));
        }
        return result;
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static BigDecimal getExternalFreeAllSpace(){
        BigDecimal result=BigDecimal.ZERO;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            File external=Environment.getExternalStorageDirectory();
            StatFs statFs=new StatFs(external.getPath());
            if(Build.VERSION_CODES.JELLY_BEAN_MR2 >Build.VERSION.SDK_INT){
                int block_size=statFs.getBlockSize();
                int block_count=statFs.getAvailableBlocks();
                result=BigDecimal.valueOf(block_size).multiply(BigDecimal.valueOf(block_count));
            }else{
                result=BigDecimal.valueOf(statFs.getAvailableBytes());
            }
        }
        return result;
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    public static BigDecimal getInternalFreeAllSpace(){
        BigDecimal result=BigDecimal.ZERO;
        File external=Environment.getRootDirectory();
        StatFs statFs=new StatFs(external.getPath());
        if(Build.VERSION_CODES.JELLY_BEAN_MR2 >Build.VERSION.SDK_INT){
            result=BigDecimal.valueOf(statFs.getAvailableBlocks()).
                    multiply(BigDecimal.valueOf(statFs.getBlockSize()));
        }else{
            result=BigDecimal.valueOf(statFs.getAvailableBytes());
        }
        return result;
    }

    /*规范 path 目录 成 /a/b/c/d/
    * */
    public static String normalizePath(String path){
        String result=String.valueOf(path);
        StringBuilder patternSb=new StringBuilder(File.separator);
        patternSb.append("+");
        String pattern=patternSb.toString();
        if(TextUtils.isEmpty(result)){
            result=File.separator;
        }else{
            StringBuilder sb=new StringBuilder(File.separator);
            sb.append(path).append(File.separator);
            result=sb.toString();
            result=result.replaceAll(pattern,File.separator);
        }
        return result;
    }

    public static String drop2Str(String path,String pattern){
        String result=String.valueOf(path);
        result= dropHeadStr(result,pattern);
        result= dropTailStr(result,pattern);
        return result;
    }

    public static String drop2SlashOfStr(String path){
        String result=String.valueOf(path);
        String pattern=File.separator+"+";
        result=drop2Str(result,pattern);
        return result;
    }

    public static String dropHeadStr(String path,String pattern){
        String result=String.valueOf(path);
        String locPattern=pattern.startsWith("^")?String.valueOf(pattern):
                "^"+pattern;
        Pattern p= Pattern.compile(locPattern);
        Matcher m=p.matcher(result);
        while (m.find()){
            String prefix=m.group();
            if(result.startsWith(prefix)){
                result= result.substring(prefix.length());
            }else{
                break;
            }
            m=p.matcher(result);
        }
        return result;
    }

    public static String dropTailStr(String path,String pattern){
        String result=path;
        String $="$";
        String locPattern=pattern.endsWith($)?String.valueOf(pattern):
                (new StringBuilder(pattern)).append($).toString();
        Pattern p= Pattern.compile(locPattern);
        Matcher m=p.matcher(result);
        while (m.find()){
            String sufix=m.group();
            if(result.endsWith(sufix)){
                result= result.substring(0,result.length()-sufix.length());
            }else{
                break;
            }
            m=p.matcher(result);
        }
        return result;
    }

    /*数组合并*/
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public static <T> T[] concatAll(T[] first, T[]... rest) {
        int totalLength = first.length;
        for (T[] array : rest) {
            if(array!=null){
                totalLength += array.length;
            }
        }
       T[] result=null;
       if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.GINGERBREAD){
            result= Arrays.copyOf(first, totalLength);
        }else{
            result= (T[]) Array.newInstance(first.getClass().getComponentType(),
                    totalLength);
             System.arraycopy(first,0,result,0,first.length);
        }
        int offset = first.length;
        for (T[] array : rest) {
            if(array!=null){
                System.arraycopy(array, 0, result, offset, array.length);
                offset += array.length;
            }
        }
        return result;
    }


    /**
     * byte数组转换成16进制字符串
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static boolean isNetConnected(Context context){
        ConnectivityManager cm= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if(cm!=null){
            //todo  网络
        }
        return false;
    }

    //去文件名的点号后缀
    public static String dropDotSuffix(String fileName){
        int lastDotIndex=fileName.lastIndexOf(".");
        String fileName1=String.valueOf(fileName);
        if(lastDotIndex!=-1){
            fileName1=fileName1.substring(0,lastDotIndex);
        }
        return fileName1;
    }

    public static boolean del(String filepath) {
        File f = new File(String.valueOf(filepath));//定义文件路径
        if(f.exists() && f.isDirectory()){//判断是文件还是目录
           if(f.listFiles().length>0){//若有则把文件放进数组，并判断是否有下级目录
                File delFile[]=f.listFiles();
                int i =f.listFiles().length;
                for(int j=0;j<i;j++) {
                    if (delFile[j].isDirectory()) {
                        del(delFile[j].getAbsolutePath());//递归调用del方法并取得子目录路径
                    }
                    delFile[j].delete();//删除文件
                }
            }
            if(f.listFiles().length==0){//若目录下没有文件则直接删除
                return f.delete();
            }
        }else if(f.exists()&&f.isFile()){
            return f.delete();
        }else if(!f.exists()){
            return true;
        }
        return false;
    }

    /**
     * Created by caoweiPc on 2014/7/30.
     */

}
